package com.chub.study.modules.service.impl;

import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chub.study.enums.RedisKeyPrefixEnum;
import com.chub.study.modules.dto.DictInfoDTO;
import com.chub.study.modules.entity.TDictInfo;
import com.chub.study.modules.mapper.TDictInfoMapper;
import com.chub.study.modules.service.TDictInfoService;
import com.chub.study.util.RedisKeyUtils;
import com.chub.study.util.RedisUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <p>
 * 字典信息表 服务实现类
 * </p>
 *
 * @author Chub
 * @since 2023-04-13
 */
@Service
@Slf4j
public class TDictInfoServiceImpl extends ServiceImpl<TDictInfoMapper, TDictInfo> implements TDictInfoService {

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    TDictInfoMapper dictInfoMapper;

    /**
     * 根据字典类型编码集合获取字典信息列表
     *
     * @param dictTypeCodes 字典类型编码集合
     * @return 字典信息列表的Map对象，key为字典类型编码，value为对应编码的字典信息列表
     */
    @Override
    public Map<String, List<TDictInfo>> getBydictTypeCodes(Set<String> dictTypeCodes)  {
        if (null == dictTypeCodes || dictTypeCodes.isEmpty() ) {
            return null;
        }

        Map<String, List<TDictInfo>> result = new HashMap<>(dictTypeCodes.size());
        Set<String> keys = new HashSet<>(dictTypeCodes.size());
        List<TDictInfo> dictInfoList = null;

        log.info("需要从redis查询的字典类型集合， dictTypeCodes:{}", JSON.toJSONString(dictTypeCodes));

        for (String typeCode : dictTypeCodes) {
            String key = RedisKeyUtils.getKey(RedisKeyPrefixEnum.DICT_TYPE_CODE, typeCode);
            log.info("redis KEY, typeCode:{}, key:{}", JSON.toJSONString(dictTypeCodes), key);

            Object obj = redisUtils.get(key);
            if (obj == null) {
                keys.add(typeCode);
                continue;
            }

            dictInfoList = (List<TDictInfo>) obj;
            if (dictInfoList == null) {
                keys.add(typeCode);
                continue;
            }
            result.put(typeCode, dictInfoList);
        }

        if (keys.isEmpty()) {
            return result;
        }

        log.info("未能从redis查询到内容，需要从数据库查询的字典类型集合,  keys:{}",  keys);
        QueryWrapper<TDictInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("DICT_TYPE_CODE", keys);
        dictInfoList = dictInfoMapper.selectList(queryWrapper);

        List<TDictInfo> tmpList = null;

        for (TDictInfo dictInfo : dictInfoList) {
            // computeIfAbsent() 方法对 hashMap 中指定 key 的值进行重新计算，如果不存在这个 key，则添加到 hashMap 中。
            tmpList = result.computeIfAbsent(dictInfo.getDictTypeCode(), k -> new ArrayList<>());
            // tmpList.add(dictInfo);

            tmpList = result.get(dictInfo.getDictTypeCode());
            if (tmpList == null) {
                tmpList = new ArrayList<>();
                result.put(dictInfo.getDictTypeCode(), tmpList);
            }
            tmpList.add(dictInfo);
        }

        log.info("从数据库查询结果集， result:{}", JSON.toJSONString(result));

        for (String type : keys) {
            tmpList = result.get(type);
            if (tmpList == null || tmpList.isEmpty()) {
                continue;
            }

            String redisKey = RedisKeyUtils.getKey(RedisKeyPrefixEnum.DICT_TYPE_CODE, type);
            log.info("写入redis， key:{}, val:{}", redisKey, JSON.toJSONString(tmpList));
            redisUtils.set(redisKey, tmpList, 1000);
        }

        // 放到redis里,尽量减少存储的内容
        List<DictInfoDTO> dtoList = dictInfoMapper.getDictInfoBydictTypeCodes(keys);
        log.info("从数据库查询结果集， dtoList:{}", JSON.toJSONString(dtoList));



        return result;
    }

    /**
     * @description : 批量插入
     *
     * @param  : dictInfos
     * @return : int
     * @author : chub
     * @date   : 2023-10-16 15:44
     */
    @Override
    public int batchInsert(List<TDictInfo> dictInfos) {

        dictInfoMapper.batchInsert(dictInfos);
        return 0;
    }

    @Override
    public int insertBatchSomeColumn(Collection<TDictInfo> dictInfos) {
        return dictInfoMapper.insertBatchSomeColumn(dictInfos);
    }





}
